﻿using Unity.Burst;
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Collections;

partial struct MeleeAttackSystem : ISystem
{

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        PhysicsWorldSingleton physicsWorldSingleton = SystemAPI.GetSingleton<PhysicsWorldSingleton>();
        CollisionWorld collisionWorld = physicsWorldSingleton.CollisionWorld;
        NativeList<RaycastHit> raycastHitList = new NativeList<RaycastHit>(Allocator.Temp);
        //UnityEngine.Debug.Log($"isTouchingTarget:1");
        foreach ((RefRO<LocalTransform> localTransform
            , RefRW<MeleeAttack> meleeAttack
            , RefRW<Target> target
            , RefRW<TargetPositionPathQueued> targetPositionPathQueued
            , EnabledRefRW<TargetPositionPathQueued> targetPositionPathQueuedEnabled)
            in SystemAPI.Query<
                RefRO<LocalTransform>
                , RefRW<MeleeAttack>
                , RefRW<Target>
                , RefRW<TargetPositionPathQueued>
                , EnabledRefRW<TargetPositionPathQueued>>().WithDisabled<MoveOverride>().WithPresent<TargetPositionPathQueued>())
        {
            if (target.ValueRO.tagertEntity == Entity.Null)
            {
                //UnityEngine.Debug.Log($"isTouchingTarget:2");
                continue;
            }
            LocalTransform targetLocalTransform = SystemAPI.GetComponent<LocalTransform>(target.ValueRO.tagertEntity);
            float meleeAttackDistanceSq = 2f;
            bool isCloseEnoughToAttack = math.distancesq(targetLocalTransform.Position, localTransform.ValueRO.Position) < meleeAttackDistanceSq;

            bool isTouchingTarget = false;
            if (isCloseEnoughToAttack == false)
            {
                float3 dirToTarget = targetLocalTransform.Position - localTransform.ValueRO.Position;
                dirToTarget = math.normalize(dirToTarget);
                float distanceExtraToTestRaycast = .4f;
                RaycastInput raycastInput = new RaycastInput
                {
                    Start = localTransform.ValueRO.Position,
                    End = localTransform.ValueRO.Position + dirToTarget * (meleeAttack.ValueRO.colliderSize + distanceExtraToTestRaycast),
                    Filter = CollisionFilter.Default,
                };
                raycastHitList.Clear();
                if (collisionWorld.CastRay(raycastInput, ref raycastHitList))
                {
                    foreach (RaycastHit raycastHit in raycastHitList)
                    {
                        if (raycastHit.Entity == target.ValueRO.tagertEntity)
                        {
                            //足够可以攻击这个实体了
                            isTouchingTarget = true;
                            break;
                        }
                    }
                }
            }

            //UnityEngine.Debug.Log($"isTouchingTarget:" + isTouchingTarget);
            //没有接近目标或者目标没有接近可攻击距离  设置向目标位置移动
            if (isCloseEnoughToAttack == false && isTouchingTarget == false)
            {
                targetPositionPathQueued.ValueRW.targetPostion = targetLocalTransform.Position;
                targetPositionPathQueuedEnabled.ValueRW = true;
            }
            else
            {
                targetPositionPathQueued.ValueRW.targetPostion = localTransform.ValueRO.Position;
                targetPositionPathQueuedEnabled.ValueRW = true;

                meleeAttack.ValueRW.timer -= SystemAPI.Time.DeltaTime;
                if (meleeAttack.ValueRW.timer > 0)
                {
                    continue;
                }

                meleeAttack.ValueRW.timer = meleeAttack.ValueRW.timerMax;
                RefRW<Health> targetHealth = SystemAPI.GetComponentRW<Health>(target.ValueRO.tagertEntity);
                targetHealth.ValueRW.healthAmount -= meleeAttack.ValueRO.damageAmount;
                targetHealth.ValueRW.onHealthChanged = true;
                meleeAttack.ValueRW.onAttack = true;
            }
        }
    }

}
